<?php
/**
 * 模型代码生成器
 */
namespace app\common\model;

use think\helper\Str;

class BuildLogic
{
    private $TAB = "    ";

    /**
     * 生成验证规则
     */
    public function buildValidate($mid)
    {
        try{
            $fields = \think\Db::table('field')->where('mid', $mid)->order('field_sort')->select();
            foreach ($fields as $v) {
                if ($v['validate_scene'] > 0 && !empty($v['validate'])) {
                    $validate = json_decode($v['validate'], true);
                    $rule[$v['field_name']]=[
                        'key'=>"{$v['field_name']}|{$v['title']}",
                        'rule'=>implode('|', $validate)
                    ];
                    if ($v['validate_scene'] == 1) {
                        $sceneAdd[$rule[$v['field_name']]['key']]=$rule[$v['field_name']]['rule'];
                    }
                    if ($v['validate_scene'] == 2) {
                        $sceneEdit[$rule[$v['field_name']]['key']]=$rule[$v['field_name']]['rule'];
                    }
                    if ($v['validate_scene'] == 3) {
                        $sceneAdd[$rule[$v['field_name']]['key']]=$rule[$v['field_name']]['rule'];
                        $sceneEdit[$rule[$v['field_name']]['key']]=$rule[$v['field_name']]['rule'];
                    }
                }
            }
            $valid['add'] = $sceneAdd;
            $valid['edit'] = $sceneEdit;
            return $valid;
        } catch (\Exception $e){
            exception($e->getMessage(),40001);
        }
    }

    /**
     * 生成模型
     */
    public function buildModel($mid)
    {
        try{
            $moudle  = \think\Db::table('moudle')->find($mid);
            $fields  = \think\Db::table('field')->where('mid', $mid)->order('field_sort')->select();
            $typeArr = [];
            $getAttr = [];
            $setAttr = [];
            $editExtend = [];
            foreach ($fields as $v) {
                $fieldName = $v['field_name']; //字段名
                $fieldNameStudly = Str::studly($v['field_name']); //驼峰法field
                //json类型转换
                if (in_array($v['field_type'], ['images', 'files'])) {
                    $set = json_decode($v['set'], true);
                    if($v['field_type']=='files'){
                        $getFilesForm=<<<CODE
    //扩展属性读取器
    public function get{$fieldNameStudly}ArrAttr(\$value, \$data)
    {
        \$list      = explode('|', \$data['{$fieldName}']);
        foreach (\$imgList as \$k => \$v) {
            \$f=explode('###',\$v);
            \$arr[\$k]['src']   = \$f[0];
            \$arr[\$k]['title']   = \$f[1];
        }
        return \$arr;
    }
CODE;
                        $getAttr[]=$getFilesForm;
                    }
                    if($set['type']=='imagesForm'){
                        $getImagesForm=<<<CODE
    //扩展属性读取器
    public function get{$fieldNameStudly}ArrAttr(\$value, \$data)
    {
        \$list      = explode('###', \$data['{$fieldName}']);
        \$imgList   = explode('|', \$list[0]); //图片
        \$titleList = explode('|', \$list[1]); //标题
        \$infoList  = explode('|', \$list[2]); //描述
        foreach (\$imgList as \$k => \$v) {
            \$arr[\$k]['src']   = \$v;
            \$arr[\$k]['title'] = \$titleList[\$k];
            \$arr[\$k]['info']  = \$infoList[\$k];
        }
        return \$arr;
    }
CODE;
                        $getAttr[]=$getImagesForm;
                    }
                    if($set['type']=='images'){
                        $getImagesForm=<<<CODE
    //扩展属性读取器
    public function get{$fieldNameStudly}ArrAttr(\$value, \$data)
    {
        \$album = explode('|', \$data['{$fieldName}']);
         return \$album;
    }
CODE;
                        $getAttr[]=$getImagesForm;
                    }
                }
                //数字类型转换
                if ($v['field_type'] == 'number') {
                    $set = json_decode($v['set'], true);
                    if ($set['field_type'] == 'decimal') {
                        $typeStr = 'float';
                    } else {
                        $typeStr = 'integer';
                    }
                    $typeArr[] = str_repeat($this->TAB, 2) . "'" . $v['field_name'] . "'=>'" . $typeStr . "'";
                }
                //box选项
                if ($v['field_type'] == 'box') {
                    $set = json_decode($v['set'], true);
                    if (in_array($set['form_type'],['radio','select'])){
                        $options = explode(',',$set['options']);
                        $optionsArr=[];
                        foreach($options as $value){
                            $key=explode('|',$value);
                            $optionsArr[]="'{$key[0]}'=>'{$key[1]}'";
                        }
                        if(!empty($optionsArr)){
                            $optionsArr=implode(',',$optionsArr);
                            $getOptions=<<<CODE
    public function get{$fieldNameStudly}TextAttr(\$value, \$data)
    {
        \$arr=[{$optionsArr}];
        return \$arr[\$data['{$fieldName}']];
    }
CODE;
                            $getAttr[]=$getOptions;
                        }
                    }
                    if ($set['form_type'] == 'checkbox') {
                        $typeArr[] = str_repeat($this->TAB, 2) . "'" . $v['field_name'] . "'=>'array'";
                        $editExtend[] = <<<CODE
    if(!array_key_exists('{$v['field_name']}',\$data)){
        \$data[{$v['field_name']}]='';
    }
CODE;
                    }
                }
                //日期类型转换
                if ($v['field_type'] == 'datetime') {
                    $set = json_decode($v['set'], true);
                    $format = 'Y-m-d H:i:s';
                    switch ($set['format']) {
                        case 1:
                            $format = 'Y-m-d';
                            break;
                        case 2:
                            $format = 'H:i:s';
                            break;
                        default:
                            break;
                    }
                    $typeArr[] = str_repeat($this->TAB, 2) . "'" . $v['field_name'] . "'=>'timestamp:" . $format . "'";
                }
                //自定义
                if($v['field_type']=='custom'){
                    $set = json_decode($v['set'], true);
                    //扩展属性
                    if($set['custom']=='widget|common/Form/extend'){
                        //考虑扩展属性为空处理
                        $editExtend[] = <<<CODE
            if(!array_key_exists('{$v['field_name']}',\$data)) {
                \$data['{$v['field_name']}'] = '';
            }
CODE;
                        $getExtend=<<<CODE
    public function get{$fieldNameStudly}Attr(\$value, \$data)
    {
        if(empty(\$value)){
            return [];
        }
        return json_decode(\$value,true);
    }
CODE;
                        $setExtend=<<<CODE
    protected function set{$fieldNameStudly}Attr(\$value, \$data)
    {
        \$item = [];
        if (\$value) {
            \$value = trim(\$value);
            \$list = explode("\\r\\n", \$value);
            foreach(\$list as \$v){
                \$v = trim(\$v);
                 if(!empty(\$v)){
                     \$v = str_replace('：',":",\$v);
                     \$arr = explode(':',\$v);
                     \$arrKey = trim(\$arr[0]);
                     \$arrValue = trim(\$arr[1]);
                     \$item[\$arrKey] = \$arrValue;
                }
            }
        }
        return json_encode(\$item,JSON_UNESCAPED_UNICODE);
    }
CODE;
                        $getAttr[]=$getExtend;
                        $setAttr[]=$setExtend;
                    }
                    //自定义多选框
                    if(strstr($set['custom'], 'widget|common/Form/custombox|checkbox')){
                        $typeArr[] = str_repeat($this->TAB, 2) . "'" . $v['field_name'] . "'=>'array'";
                        $editExtend[] = <<<CODE
            if(!array_key_exists('{$v['field_name']}',\$data)){
                \$data[{$v['field_name']}]='';
            }
CODE;
                    }
                }
                //富文本读取器
                if ($v['field_type'] == 'editor') {
                    $editor=<<<CODE
    protected function getContentAttr(\$value)
    {
        return stripslashes(htmlspecialchars_decode(\$value));
    }
CODE;
                    $getAttr[] = $editor;
                }
            }
            $moudleName = Str::studly($moudle['table_name']);
            $tableName  = $moudle['table_name'];
            $typeArr    = implode(',' . PHP_EOL, $typeArr);
            $getAttr    = implode(PHP_EOL, $getAttr);
            $setAttr    = implode(PHP_EOL, $setAttr);
            $editExtend = implode(PHP_EOL,$editExtend);
            $str        = <<<CODE
namespace app\common\model\logic;

use think\Model;

class {$moudleName}Model extends Model {

    protected \$name = '{$tableName}'; //定义栏目表
    //开启自动写入时间戳
    protected \$autoWriteTimestamp = true;
    //类型自动转换
    protected \$type = [
{$typeArr}
    ];
{$getAttr}

{$setAttr}
    /**
     * 获取检索条件
     * @param \$query
     */
    public function getExtendMap(\$query){
        return [];
    }

    //读取单条数据
    public function read(\$aid){
        try{
            \$info = \$this->get(\$aid)->toArray();
            return \$info;
        } catch (\Exception \$e){
            exception(\$e->getMessage(),40001);
        }
    }
    
    //格式化列表
    public function formatList(\$list){
        return \$list;
    }
    //格式化单条内容
    public function formatInfo(\$info){
        return \$info;
    }
    
    //添加数据
    public function add(\$data){
        try{
            \$this->isUpdate(false)->allowField(true)->save(\$data);
            return true;
        }catch (\Exception \$e){
            exception(\$e->getMessage(),40001);
        }
    }
    //修改数据
    public function edit(\$data){
        try{
{$editExtend}
            \$this->isUpdate(true)->allowField(true)->save(\$data);
            return true;
        } catch (\Exception \$e){
            exception(\$e->getMessage(),40001);
        }
    }
    //删除数据
    public function del(\$aid){
        try{
            \$this->destroy(\$aid);
            return true;
        } catch (\Exception \$e){
            exception(\$e->getMessage(),40001);
        }
    }
}
CODE;
            return $str;
        } catch (\Exception $e){
            exception($e->getMessage(),40001);
        }
    }

}
